﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright company="Microsoft Corporation" file="CarTests.cs">
//   Copyright Microsoft Corporation. All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) This is sample code only, do not use in production environments.
// </copyright>
// <summary>
//   Contains unit tests for the Car class.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Microsoft.ALMRangers.FakesGuide.ComplexDependencies.Traffic.Core.Tests
{
    using System.Windows.Media;
    using Microsoft.ALMRangers.FakesGuide.ComplexDependencies.Traffic.Core.Algorithms.Fakes;
    using Microsoft.ALMRangers.FakesGuide.ComplexDependencies.Traffic.Core.Models;
    using Microsoft.ALMRangers.FakesGuide.ComplexDependencies.Traffic.Core.Models.Fakes;
    using Microsoft.QualityTools.Testing.Fakes;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class CarTests
    {
        /// <summary>
        /// Test to ensure that the Car constructor should initialize the Car vehicle color, routing algorithm and random generator properties
        /// </summary>
        [TestMethod]
        public void Car_Constructor_ShouldInitializeDependentPropertiesSuccessfully()
        {
            var expectedAlgorithm = new StubRoutingAlgorithm();
            var expectedColor = Brushes.Aqua;
            Car codeUnderTest = new Car(expectedAlgorithm, expectedColor);

            Assert.AreSame(expectedAlgorithm, codeUnderTest.Routing, "The Car constructor should initialize the routing algorithm correctly.");
            Assert.AreEqual(expectedColor, codeUnderTest.VehicleColor, "The Car constructor should initialize the vehicle color correctly.");
            Assert.IsNotNull(codeUnderTest.RandomGenerator, "The Car constructor should initialize the random generator correctly.");
        }

        /// <summary>
        /// Test to ensure that the Car.ShouldMove property returns false where Location is null.
        /// </summary>
        [TestMethod]
        public void Car_ShouldMoveProperty_ReturnsFalseIfLocationIsNull()
        {
            var stubAlgorithm = new StubRoutingAlgorithm();
            var testBrush = Brushes.AliceBlue;
            Car codeUnderTest = new Car(stubAlgorithm, testBrush);
            codeUnderTest.Location = null;

            Assert.IsFalse(codeUnderTest.ShouldMove, "The Car.ShouldMove property should return false where Car.Location is null.");
        }

        /// <summary>
        /// Test to ensure that the Car.ShouldMove property returns false where Location is null.
        /// </summary>
        [TestMethod]
        public void Car_ShouldMoveProperty_ReturnsFalseIfLocationRoadPropertyIsNull()
        {
            var stubAlgorithm = new StubRoutingAlgorithm();
            var testBrush = Brushes.AliceBlue;
            Car codeUnderTest = new Car(stubAlgorithm, testBrush);
            codeUnderTest.Location = new StubElementLocation { Road = null };

            Assert.IsFalse(codeUnderTest.ShouldMove, "The Car.ShouldMove property should return false where Car.Location.Road is null.");
        }

        /// <summary>
        /// Test to ensure that the Car.ShouldMove property returns false where Location.Road.IsFree returns false.
        /// </summary>
        [TestMethod]
        public void Car_ShouldMoveProperty_ReturnsFalseIfLocationRoadIsFreeReturnsFalse()
        {
            var stubAlgorithm = new StubRoutingAlgorithm();
            var testBrush = Brushes.AliceBlue;
            using (ShimsContext.Create())
            {
                // Ensure any calls to Block.IsFree return false.
                ShimBlock.AllInstances.IsFreeInt32 = (block, position) => false;

                Car codeUnderTest = new Car(stubAlgorithm, testBrush);
                codeUnderTest.Location = new StubElementLocation
                {
                    Road = new StubBlock()
                };

                Assert.IsFalse(codeUnderTest.ShouldMove, "The Car.ShouldMove property should return false where calls to Blocks.IsFree return false.");
            }
        }
    }
}
